home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / aplictns / dkbtrace / part09 < prev    next >
Encoding:
Internet Message Format  |  1990-09-03  |  66.6 KB

  1. Path: abcfd20.larc.nasa.gov!amiga-request
  2. From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v90i257: DKBTrace 2.01 - DKBtrace Ray-Tracer, Part09/10
  4. Reply-To: David Schanen <mtv@milton.u.washington.edu>
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v90i257@abcfd20.larc.nasa.gov>
  7. References: <comp.sources.amiga:v90i249@abcfd20.larc.nasa.gov>
  8. Date: 03 Sep 90 23:22:40 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga
  12.  
  13. Submitted-by: David Schanen <mtv@milton.u.washington.edu>
  14. Posting-number: Volume 90, Issue 257
  15. Archive-name: applications/dkbtrace-2.01/part09
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 9 (of 10)."
  24. # Contents:  src/parse.c
  25. # Wrapped by tadguy@abcfd20 on Mon Sep  3 19:21:22 1990
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'src/parse.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'src/parse.c'\"
  29. else
  30. echo shar: Extracting \"'src/parse.c'\" \(63678 characters\)
  31. sed "s/^X//" >'src/parse.c' <<'END_OF_FILE'
  32. X/*****************************************************************************
  33. X*
  34. X*                                    parse.c
  35. X*
  36. X*   from DKBTrace (c) 1990  David Buck
  37. X*
  38. X*  This module implements a parser for the scene description files.
  39. X*
  40. X* This software is freely distributable. The source and/or object code may be
  41. X* copied or uploaded to communications services so long as this notice remains
  42. X* at the top of each file.  If any changes are made to the program, you must
  43. X* clearly indicate in the documentation and in the programs startup message
  44. X* who it was who made the changes. The documentation should also describe what
  45. X* those changes were. This software may not be included in whole or in
  46. X* part into any commercial package without the express written consent of the
  47. X* author.  It may, however, be included in other public domain or freely
  48. X* distributed software so long as the proper credit for the software is given.
  49. X*
  50. X* This software is provided as is without any guarantees or warranty. Although
  51. X* the author has attempted to find and correct any bugs in the software, he
  52. X* is not responsible for any damage caused by the use of the software.  The
  53. X* author is under no obligation to provide service, corrections, or upgrades
  54. X* to this package.
  55. X*
  56. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  57. X* about them.  Also, if you have any comments or questions, you may contact me
  58. X* at the following address:
  59. X*
  60. X*     David Buck
  61. X*     22C Sonnet Cres.
  62. X*     Nepean Ontario
  63. X*     Canada, K2H 8W7
  64. X*
  65. X*  I can also be reached on the following bulleton boards:
  66. X*
  67. X*     ATX              (613) 526-4141
  68. X*     OMX              (613) 731-3419
  69. X*     Mystic           (613) 731-0088 or (613) 731-6698
  70. X*
  71. X*  Fidonet:   1:163/109.9
  72. X*  Internet:  David_Buck@Carleton.CA
  73. X*
  74. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  75. X*
  76. X*     Lattice BBS                      (708) 916-1200
  77. X*     The Information Exchange BBS     (708) 945-5575
  78. X*     Stillwaters BBS                  (708) 403-2826
  79. X*
  80. X*****************************************************************************/
  81. X
  82. X#include "frame.h"
  83. X#include "vector.h"
  84. X#include "dkbproto.h"
  85. X
  86. X/* This file implements a simple recursive-descent parser for reading the
  87. Xinput file.  */
  88. X
  89. Xextern FILE *Token_File;
  90. XFRAME *Parsing_Frame_Ptr;
  91. Xchar Current_File_Name[20];
  92. X
  93. Xextern METHODS Composite_Methods;
  94. Xextern METHODS Basic_Object_Methods;
  95. Xextern METHODS Sphere_Methods;
  96. Xextern METHODS Quadric_Methods;
  97. Xextern METHODS Viewpoint_Methods;
  98. Xextern METHODS Plane_Methods;
  99. Xextern METHODS Triangle_Methods;
  100. Xextern METHODS Smooth_Triangle_Methods;
  101. Xextern METHODS CSG_Union_Methods;
  102. Xextern METHODS CSG_Intersection_Methods;
  103. X
  104. Xextern struct Reserved_Word_Struct Reserved_Words [];
  105. Xextern DBL Antialias_Threshold;
  106. X
  107. Xstruct Token_Struct Token;
  108. X
  109. X#define MAX_CONSTANTS 100
  110. Xstruct Constant_Struct Constants[MAX_CONSTANTS];
  111. Xint Number_Of_Constants;
  112. XTEXTURE *Default_Texture;
  113. Xint Degenerate_Triangles;
  114. X
  115. X/* Here we create out own little language for doing the parsing.  It
  116. Xmakes the code easier to read. */
  117. X
  118. X#define EXPECT { int Exit_Flag; Exit_Flag = FALSE; \
  119. X while (!Exit_Flag) {Get_Token();  switch (Token.Token_Id) {
  120. X#define CASE(x) case x:
  121. X#define CASE2(x, y) case x: case y:
  122. X#define CASE3(x, y, z) case x: case y: case z:
  123. X#define CASE4(w, x, y, z) case w: case x: case y: case z:
  124. X#define CASE5(v, w, x, y, z) case v: case w: case x: case y: case z:
  125. X#define END_CASE break;
  126. X#define EXIT Exit_Flag = TRUE;
  127. X#define OTHERWISE default:
  128. X#define END_EXPECT } } }
  129. X#define GET(x) Get_Token(); if (Token.Token_Id != x) Parse_Error (x)
  130. X#define UNGET Unget_Token();
  131. X
  132. X/* Parse the file into the given frame. */
  133. Xvoid Parse (File, Frame_Ptr)
  134. X  FILE *File;
  135. X  FRAME *Frame_Ptr;
  136. X  {
  137. X  Token_File = File;
  138. X  Parsing_Frame_Ptr = Frame_Ptr;
  139. X
  140. X  Degenerate_Triangles = FALSE;
  141. X  Token_Init ();
  142. X  Frame_Init ();
  143. X  Parse_Frame ();
  144. X  if (Degenerate_Triangles) {
  145. X     printf ("Cannot continue due to degenerate triangles.\n");
  146. X     exit(1);
  147. X     }
  148. X  }
  149. X
  150. Xvoid Token_Init ()
  151. X  {
  152. X  Token.Unget_Token = FALSE;
  153. X  Token.End_Of_File = FALSE;
  154. X  Number_Of_Constants = 0;
  155. X  }
  156. X
  157. X/* Read a token from the input file and store it in the Token variable.
  158. XIf the token is an INCLUDE token, then set the include file name and
  159. Xread another token. */
  160. X
  161. Xint Get_Token ()
  162. X  {
  163. X  char *str_ptr;
  164. X  int Token_Id;
  165. X
  166. X  if (Token.Unget_Token)
  167. X    {
  168. X    Token.Unget_Token = FALSE;
  169. X    return (TRUE);
  170. X    }
  171. X
  172. X  if (Token.End_Of_File)
  173. X    {
  174. X    return (FALSE);
  175. X    }
  176. X  
  177. X  if (fscanf (Token_File, "%d %d", &Token_Id, &Token.Token_Line_No)
  178. X       != 2)
  179. X    {
  180. X    Token.End_Of_File = TRUE;
  181. X    Token.Token_Id    = END_OF_FILE_TOKEN;
  182. X    return (TRUE);
  183. X    }
  184. X
  185. X  Token.Token_Id = Token_Id;
  186. X
  187. X  getc(Token_File);
  188. X  if (fgets (Token.Token_String, FILE_NAME_LENGTH, Token_File) == NULL)
  189. X    {
  190. X    Token.End_Of_File = TRUE;
  191. X    Token.Token_Id    = END_OF_FILE_TOKEN;
  192. X    return (TRUE);
  193. X    }
  194. X
  195. X  if ((str_ptr = strchr(Token.Token_String, '\n')) != NULL)
  196. X     *str_ptr = '\0';
  197. X
  198. X  if (Token.Token_Id == FLOAT_TOKEN)
  199. X    if (sscanf (Token.Token_String, DBL_FORMAT_STRING, &(Token.Token_Float)) != 1)
  200. X      {
  201. X      printf ("Premature end of file in token file\n");
  202. X      printf ("Could not read float: %s\n", Token.Token_String);
  203. X      Token.End_Of_File = TRUE;
  204. X      Token.Token_Id    = END_OF_FILE_TOKEN;
  205. X      return (TRUE);
  206. X      }
  207. X
  208. X  if (Token.Token_Id == INCLUDE_TOKEN) {
  209. X     strcpy (Current_File_Name, Token.Token_String);
  210. X     return (Get_Token());
  211. X     }
  212. X
  213. X  if (Token.Token_Id > LAST_TOKEN)
  214. X    {
  215. X    Token.Identifier_Number = (int) Token.Token_Id - (int) LAST_TOKEN;
  216. X    Token.Token_Id = IDENTIFIER_TOKEN;
  217. X    }
  218. X
  219. X  return (TRUE);
  220. X  }
  221. X
  222. X
  223. X/* Mark that the token has been put back into the input stream.  The next
  224. Xcall to Get_Token will return the last-read token instead of reading a
  225. Xnew one from the file. */
  226. X
  227. Xvoid Unget_Token ()
  228. X  {
  229. X  Token.Unget_Token = TRUE;
  230. X  }
  231. X
  232. X/* Set up the fields in the frame to default values. */
  233. Xvoid Frame_Init ()
  234. X  {
  235. X  Default_Texture = Get_Texture();
  236. X  Init_Viewpoint(&(Parsing_Frame_Ptr -> View_Point));
  237. X  Parsing_Frame_Ptr -> Light_Sources = NULL;
  238. X  Parsing_Frame_Ptr -> Objects = NULL;
  239. X  Parsing_Frame_Ptr -> Atmosphere_IOR = 1.0;
  240. X  Parsing_Frame_Ptr -> Antialias_Threshold = Antialias_Threshold;
  241. X  Parsing_Frame_Ptr -> Fog_Distance = 0.0;
  242. X  Make_Colour (&(Parsing_Frame_Ptr->Fog_Colour), 0.0, 0.0, 0.0);
  243. X  }
  244. X
  245. X/* Allocate and initialize a composite object. */
  246. XCOMPOSITE *Get_Composite_Object()
  247. X  {
  248. X  COMPOSITE *New_Composite;
  249. X
  250. X  if ((New_Composite = (COMPOSITE *) malloc (sizeof (COMPOSITE)))
  251. X        == NULL)
  252. X    Error ("Cannot allocate object");
  253. X
  254. X  New_Composite -> Objects = NULL;
  255. X  New_Composite -> Next_Object = NULL;
  256. X  New_Composite -> Next_Light_Source = NULL;
  257. X  New_Composite -> Bounding_Shapes = NULL;
  258. X  New_Composite -> Type = COMPOSITE_TYPE;
  259. X  New_Composite -> Methods = &Composite_Methods;
  260. X  return (New_Composite);
  261. X  }
  262. X
  263. X/* Allocate and initialize a sphere. */
  264. XSPHERE *Get_Sphere_Shape()
  265. X  {
  266. X  SPHERE *New_Shape;
  267. X
  268. X  if ((New_Shape = (SPHERE *) malloc (sizeof (SPHERE))) == NULL)
  269. X    Error ("Cannot allocate shape");
  270. X
  271. X  Make_Vector (&(New_Shape -> Center), 0.0, 0.0, 0.0);
  272. X  New_Shape->Radius = 1.0;
  273. X  New_Shape->Radius_Squared = 1.0;
  274. X  New_Shape->Inverse_Radius = 1.0;
  275. X  New_Shape -> Type = SPHERE_TYPE;
  276. X  New_Shape -> Next_Object = NULL;
  277. X  New_Shape -> Methods = &Sphere_Methods;
  278. X  New_Shape -> VPCached = FALSE;
  279. X  New_Shape -> Inverted = FALSE;
  280. X  return (New_Shape);
  281. X  }
  282. X
  283. X/* Allocate and initialize a quadric surface. */
  284. XQUADRIC *Get_Quadric_Shape()
  285. X  {
  286. X  QUADRIC *New_Shape;
  287. X
  288. X  if ((New_Shape = (QUADRIC *) malloc (sizeof (QUADRIC))) == NULL)
  289. X    Error ("Cannot allocate shape");
  290. X
  291. X  Make_Vector (&(New_Shape -> Object_2_Terms), 1.0, 1.0, 1.0);
  292. X  Make_Vector (&(New_Shape -> Object_Mixed_Terms), 0.0, 0.0, 0.0);
  293. X  Make_Vector (&(New_Shape -> Object_Terms), 0.0, 0.0, 0.0);
  294. X  New_Shape -> Object_Constant = 1.0;
  295. X  New_Shape -> Object_VP_Constant = HUGE_VAL;
  296. X  New_Shape -> Constant_Cached = FALSE;
  297. X  New_Shape -> Non_Zero_Square_Term = FALSE;
  298. X  New_Shape -> Type = QUADRIC_TYPE;
  299. X  New_Shape -> Next_Object = NULL;
  300. X  New_Shape -> Methods = &Quadric_Methods;
  301. X  return (New_Shape);
  302. X  }
  303. X
  304. X/* Allocate and initialize a plane. */
  305. XPLANE *Get_Plane_Shape()
  306. X  {
  307. X  PLANE *New_Shape;
  308. X
  309. X  if ((New_Shape = (PLANE *) malloc (sizeof (PLANE))) == NULL)
  310. X    Error ("Cannot allocate shape");
  311. X
  312. X  Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  313. X  New_Shape->Distance = 0.0;
  314. X  New_Shape -> Type = PLANE_TYPE;
  315. X  New_Shape -> Next_Object = NULL;
  316. X  New_Shape -> Methods = &Plane_Methods;
  317. X  New_Shape -> VPCached = 0;
  318. X  return (New_Shape);
  319. X  }
  320. X
  321. X/* Allocate and initialize a triangle. */
  322. XTRIANGLE *Get_Triangle_Shape()
  323. X  {
  324. X  TRIANGLE *New_Shape;
  325. X
  326. X  if ((New_Shape = (TRIANGLE *) malloc (sizeof (TRIANGLE))) == NULL)
  327. X    Error ("Cannot allocate shape");
  328. X
  329. X  Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  330. X  Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0);
  331. X  Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0);
  332. X  Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0);
  333. X  New_Shape->Distance = 0.0;
  334. X  New_Shape->Inverted = FALSE;
  335. X  New_Shape -> Type = TRIANGLE_TYPE;
  336. X  New_Shape -> Next_Object = NULL;
  337. X  New_Shape -> Methods = &Triangle_Methods;
  338. X  New_Shape -> VPCached = FALSE;
  339. X  return (New_Shape);
  340. X  }
  341. X
  342. X/* Allocate and initialize a smooth triangle. */
  343. XSMOOTH_TRIANGLE *Get_Smooth_Triangle_Shape()
  344. X  {
  345. X  SMOOTH_TRIANGLE *New_Shape;
  346. X
  347. X  if ((New_Shape = (SMOOTH_TRIANGLE *) malloc (sizeof (SMOOTH_TRIANGLE))) == NULL)
  348. X    Error ("Cannot allocate shape");
  349. X
  350. X  Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  351. X  Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0);
  352. X  Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0);
  353. X  Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0);
  354. X  Make_Vector (&(New_Shape -> N1), 0.0, 1.0, 0.0);
  355. X  Make_Vector (&(New_Shape -> DN12), 0.0, 1.0, 0.0);
  356. X  Make_Vector (&(New_Shape -> DN13), 0.0, 1.0, 0.0);
  357. X  New_Shape->Distance = 0.0;
  358. X  New_Shape -> Type = SMOOTH_TRIANGLE_TYPE;
  359. X  New_Shape->Inverted = FALSE;
  360. X  New_Shape -> Next_Object = NULL;
  361. X  New_Shape -> Methods = &Smooth_Triangle_Methods;
  362. X  New_Shape -> VPCached = 0;
  363. X  return (New_Shape);
  364. X  }
  365. X
  366. XCSG_SHAPE *Get_CSG_Shape()
  367. X  {
  368. X  CSG_SHAPE *New_Shape;
  369. X
  370. X  if ((New_Shape = (CSG_SHAPE *) malloc (sizeof (CSG_SHAPE))) == NULL)
  371. X    Error ("Cannot allocate shape");
  372. X
  373. X  New_Shape -> Parent_Object = NULL;
  374. X  New_Shape -> Next_Object = NULL;
  375. X  New_Shape -> Shapes = NULL;
  376. X  return (New_Shape);
  377. X  }
  378. X
  379. XCSG_SHAPE *Get_CSG_Union()
  380. X  {
  381. X  CSG_SHAPE *New_Shape;
  382. X
  383. X  New_Shape = Get_CSG_Shape();
  384. X  New_Shape -> Methods = &CSG_Union_Methods;
  385. X  New_Shape -> Type = CSG_UNION_TYPE;
  386. X  return (New_Shape);
  387. X  }
  388. X
  389. XCSG_SHAPE *Get_CSG_Intersection()
  390. X  {
  391. X  CSG_SHAPE *New_Shape;
  392. X
  393. X  New_Shape = Get_CSG_Shape();
  394. X  New_Shape -> Methods = &CSG_Intersection_Methods;
  395. X  New_Shape -> Type = CSG_INTERSECTION_TYPE;
  396. X  return (New_Shape);
  397. X  }
  398. X
  399. XOBJECT *Get_Object ()
  400. X  {
  401. X  OBJECT *New_Object;
  402. X
  403. X  if ((New_Object = (OBJECT *) malloc (sizeof (OBJECT))) == NULL)
  404. X    Error ("Cannot allocate object");
  405. X
  406. X  Make_Vector (&(New_Object -> Object_Center), 0.0, 0.0, 0.0);
  407. X
  408. X  New_Object -> Next_Object = NULL;
  409. X  New_Object -> Next_Light_Source = NULL;
  410. X  New_Object -> Shape = NULL;
  411. X  New_Object -> Bounding_Shapes = NULL;
  412. X  New_Object -> Object_Texture = Default_Texture;
  413. X
  414. X  Make_Colour (&New_Object->Object_Colour, 0.0, 0.0, 0.0);
  415. X
  416. X  New_Object -> Light_Source_Flag = FALSE;
  417. X  New_Object -> Transparency = FALSE;
  418. X  New_Object -> Type = OBJECT_TYPE;
  419. X  New_Object -> Methods = &Basic_Object_Methods;
  420. X  return (New_Object);
  421. X  }
  422. X
  423. XTEXTURE *Get_Texture ()
  424. X   {
  425. X   TEXTURE *New_Texture;
  426. X
  427. X   if ((New_Texture = (TEXTURE *) malloc (sizeof (TEXTURE))) == NULL)
  428. X     Error ("Cannot allocate object");
  429. X
  430. X   New_Texture -> Object_Reflection = 0.0;
  431. X   New_Texture -> Object_Ambient = 0.3;
  432. X   New_Texture -> Object_Diffuse = 0.7;
  433. X   New_Texture -> Object_Brilliance = 1.0;
  434. X   New_Texture -> Object_Specular = 0.0;
  435. X   New_Texture -> Object_Roughness = 0.05;
  436. X   New_Texture -> Object_Phong = 0.0;
  437. X   New_Texture -> Object_PhongSize = 40;
  438. X
  439. X   New_Texture -> Texture_Randomness= 0.0;
  440. X   New_Texture -> Bump_Amount = 0.0;
  441. X   New_Texture -> Phase = 0.0;
  442. X   New_Texture -> Frequency = 1.0;
  443. X   New_Texture -> Texture_Number = 0;
  444. X   New_Texture -> Texture_Transformation = NULL;
  445. X   New_Texture -> Bump_Number = NO_BUMPS;
  446. X   New_Texture -> Turbulence = 0.0;
  447. X   New_Texture -> Colour_Map = NULL;
  448. X   New_Texture -> Once_Flag = FALSE;
  449. X   Make_Colour (&New_Texture -> Colour1, 0.0, 0.0, 0.0);
  450. X   Make_Colour (&New_Texture -> Colour2, 0.0, 0.0, 0.0);
  451. X   Make_Vector (&New_Texture->Texture_Gradient, 0.0, 0.0, 0.0);
  452. X
  453. X   New_Texture -> Object_Index_Of_Refraction = 1.0;
  454. X   New_Texture -> Object_Refraction = 0.0;
  455. X
  456. X   return (New_Texture);
  457. X   }
  458. X
  459. XVIEWPOINT *Get_Viewpoint ()
  460. X  {
  461. X  VIEWPOINT *New_Viewpoint;
  462. X
  463. X  if ((New_Viewpoint = (VIEWPOINT *)malloc (sizeof (VIEWPOINT)))
  464. X        == NULL)
  465. X    Error ("Cannot allocate viewpoint");
  466. X
  467. X  Init_Viewpoint (New_Viewpoint);
  468. X  return (New_Viewpoint);
  469. X  }
  470. X
  471. XCOLOUR *Get_Colour ()
  472. X  {
  473. X  COLOUR *New_Colour;
  474. X
  475. X  if ((New_Colour = (COLOUR *) malloc (sizeof (COLOUR))) == NULL)
  476. X    Error ("Cannot allocate colour");
  477. X
  478. X  Make_Colour (New_Colour, 0.0, 0.0, 0.0);
  479. X  return (New_Colour);
  480. X  }
  481. X
  482. XVECTOR *Get_Vector ()
  483. X  {
  484. X  VECTOR *New_Vector;
  485. X
  486. X  if ((New_Vector = (VECTOR *) malloc (sizeof (VECTOR))) == NULL)
  487. X    Error ("Cannot allocate vector");
  488. X
  489. X  New_Vector -> x = 0.0;
  490. X  New_Vector -> y = 0.0;
  491. X  New_Vector -> z = 0.0;
  492. X  return (New_Vector);
  493. X  }
  494. X
  495. XDBL *Get_Float ()
  496. X  {
  497. X  DBL *New_Float;
  498. X
  499. X  if ((New_Float = (DBL *) malloc (sizeof (DBL))) == NULL)
  500. X    Error ("Cannot allocate float");
  501. X
  502. X  *New_Float = 0.0;
  503. X  return (New_Float);
  504. X  }
  505. X
  506. XTRANSFORMATION *Get_Transformation()
  507. X  {
  508. X  TRANSFORMATION *New_Transformation;
  509. X
  510. X  if ((New_Transformation =
  511. X        (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION))) == NULL)
  512. X    Error ("Cannot allocate transformation");
  513. X
  514. X  MIdentity ((MATRIX *) &(New_Transformation -> matrix[0][0]));
  515. X  MIdentity ((MATRIX *) &(New_Transformation -> inverse[0][0]));
  516. X  return (New_Transformation);
  517. X  }
  518. X
  519. X/* Parse a float.  Doesn't handle exponentiation. */
  520. XDBL Parse_Float ()
  521. X  {
  522. X  DBL Local_Float;
  523. X  CONSTANT Constant_Id;
  524. X  register int Negative, Sign_Parsed;
  525. X
  526. X  Negative = FALSE;
  527. X  Sign_Parsed = FALSE;
  528. X
  529. X  EXPECT
  530. X    CASE (IDENTIFIER_TOKEN)
  531. X      if ((Constant_Id = Find_Constant()) != -1)
  532. X        if (Constants[(int)Constant_Id].Constant_Type == FLOAT_CONSTANT)
  533. X          {
  534. X          Local_Float = *((DBL *) Constants[(int)Constant_Id].Constant_Data);
  535. X          if (Negative)
  536. X            Local_Float *= -1.0;
  537. X          }
  538. X        else
  539. X          Type_Error ();
  540. X      else
  541. X        Undeclared ();
  542. X      EXIT
  543. X    END_CASE
  544. X
  545. X    CASE (PLUS_TOKEN)
  546. X      if (Sign_Parsed)
  547. X        Parse_Error (FLOAT_TOKEN);
  548. X      Sign_Parsed = TRUE;
  549. X    END_CASE
  550. X
  551. X    CASE (DASH_TOKEN)
  552. X      if (Sign_Parsed)
  553. X        Parse_Error (FLOAT_TOKEN);
  554. X      Negative = TRUE;
  555. X      Sign_Parsed = TRUE;
  556. X    END_CASE
  557. X
  558. X    CASE (FLOAT_TOKEN)
  559. X      Local_Float = Token.Token_Float;
  560. X      if (Negative)
  561. X        Local_Float *= -1.0;
  562. X      EXIT
  563. X    END_CASE
  564. X
  565. X    OTHERWISE
  566. X      Parse_Error (FLOAT_TOKEN);
  567. X    END_CASE
  568. X  END_EXPECT
  569. X
  570. X  return (Local_Float);
  571. X  }
  572. X
  573. Xvoid Parse_Vector (Given_Vector)
  574. X  VECTOR *Given_Vector;
  575. X  {
  576. X  CONSTANT Constant_Id;
  577. X
  578. X  EXPECT
  579. X    CASE (IDENTIFIER_TOKEN)
  580. X      if ((Constant_Id = Find_Constant()) != -1)
  581. X        if (Constants[(int)Constant_Id].Constant_Type == VECTOR_CONSTANT)
  582. X          *Given_Vector = *((VECTOR *) Constants[(int)Constant_Id].Constant_Data);
  583. X        else
  584. X          Type_Error ();
  585. X      else
  586. X        Undeclared ();
  587. X      EXIT
  588. X    END_CASE
  589. X
  590. X    CASE (LEFT_ANGLE_TOKEN)
  591. X      (Given_Vector -> x) = Parse_Float();
  592. X      (Given_Vector -> y) = Parse_Float();
  593. X      (Given_Vector -> z) = Parse_Float();
  594. X      GET (RIGHT_ANGLE_TOKEN);
  595. X      EXIT
  596. X    END_CASE
  597. X
  598. X    OTHERWISE 
  599. X      Parse_Error (LEFT_ANGLE_TOKEN);
  600. X    END_CASE
  601. X  END_EXPECT
  602. X  }
  603. X
  604. Xvoid Parse_Colour (Given_Colour)
  605. X  COLOUR *Given_Colour;
  606. X  {
  607. X  CONSTANT Constant_Id;
  608. X
  609. X  Make_Colour (Given_Colour, 0.0, 0.0, 0.0);
  610. X  EXPECT
  611. X    CASE (IDENTIFIER_TOKEN)
  612. X      if ((Constant_Id = Find_Constant()) != -1)
  613. X        if (Constants[(int)Constant_Id].Constant_Type == COLOUR_CONSTANT)
  614. X          *Given_Colour = *((COLOUR *) Constants[(int)Constant_Id].Constant_Data);
  615. X        else
  616. X          Type_Error ();
  617. X      else
  618. X        Undeclared ();
  619. X    END_CASE
  620. X
  621. X    CASE (RED_TOKEN)
  622. X      (Given_Colour -> Red) = Parse_Float();
  623. X    END_CASE
  624. X
  625. X    CASE (GREEN_TOKEN)
  626. X      (Given_Colour -> Green) = Parse_Float();
  627. X    END_CASE
  628. X
  629. X    CASE (BLUE_TOKEN)
  630. X      (Given_Colour -> Blue) = Parse_Float();
  631. X    END_CASE
  632. X
  633. X    CASE (ALPHA_TOKEN)
  634. X      (Given_Colour -> Alpha) = Parse_Float();
  635. X    END_CASE
  636. X
  637. X    OTHERWISE
  638. X      UNGET
  639. X      EXIT
  640. X    END_CASE
  641. X  END_EXPECT
  642. X  }
  643. X
  644. XCOLOUR_MAP *Parse_Colour_Map ()
  645. X   {
  646. X#define MAX_ENTRIES 20
  647. X   COLOUR_MAP *New_Colour_Map;
  648. X   register int i;
  649. X
  650. X   New_Colour_Map = (COLOUR_MAP *)
  651. X                        malloc (sizeof (COLOUR_MAP));
  652. X
  653. X   if (New_Colour_Map == NULL)
  654. X      Error ("Not enough memory for colour map");
  655. X
  656. X   New_Colour_Map -> Colour_Map_Entries = (COLOUR_MAP_ENTRY *)
  657. X                  malloc(MAX_ENTRIES * sizeof (COLOUR_MAP_ENTRY));
  658. X
  659. X   if (New_Colour_Map -> Colour_Map_Entries == NULL)
  660. X      Error ("Not enough memory for colour map");
  661. X
  662. X   i = 0;
  663. X   EXPECT
  664. X      CASE (LEFT_SQUARE_TOKEN)
  665. X         New_Colour_Map -> Colour_Map_Entries [i].start = Parse_Float();
  666. X         New_Colour_Map -> Colour_Map_Entries [i].end = Parse_Float();
  667. X         GET (COLOUR_TOKEN);
  668. X         Parse_Colour (&(New_Colour_Map->Colour_Map_Entries[i].Start_Colour));
  669. X         GET (COLOUR_TOKEN);
  670. X         Parse_Colour (&(New_Colour_Map->Colour_Map_Entries[i].End_Colour));
  671. X         i++;
  672. X         if (i > MAX_ENTRIES)
  673. X            Error ("Colour_Map too long");
  674. X         GET (RIGHT_SQUARE_TOKEN);
  675. X      END_CASE
  676. X
  677. X      CASE2 (END_COLOUR_MAP_TOKEN, END_COLOR_MAP_TOKEN)
  678. X          New_Colour_Map -> Number_Of_Entries = i;
  679. X          EXIT
  680. X      END_CASE
  681. X
  682. X      OTHERWISE
  683. X         Parse_Error (END_COLOUR_MAP_TOKEN);
  684. X      END_CASE
  685. X   END_EXPECT
  686. X   return (New_Colour_Map);
  687. X   }
  688. X
  689. XTEXTURE *Copy_Texture (Texture)
  690. X   TEXTURE *Texture;
  691. X   {
  692. X   TEXTURE *New_Texture;
  693. X   New_Texture = Get_Texture();
  694. X   *New_Texture = *Texture;
  695. X   if (New_Texture->Texture_Transformation) {
  696. X      New_Texture->Texture_Transformation = (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION));
  697. X      *New_Texture->Texture_Transformation = *Texture->Texture_Transformation;
  698. X      }
  699. X   return (New_Texture);
  700. X   }
  701. X
  702. XTEXTURE *Parse_Texture (Old_Texture)
  703. X   TEXTURE *Old_Texture;
  704. X   {
  705. X   VECTOR Local_Vector;
  706. X   TRANSFORMATION Local_Transformation;
  707. X   CONSTANT Constant_Id;
  708. X   TEXTURE *Texture;
  709. X   int Texture_Constant;
  710. X
  711. X   Texture = Old_Texture;
  712. X   Texture_Constant = TRUE;
  713. X
  714. X   EXPECT
  715. X      CASE (IDENTIFIER_TOKEN)
  716. X         if ((Constant_Id = Find_Constant()) != -1)
  717. X            if (Constants[(int)Constant_Id].Constant_Type == TEXTURE_CONSTANT) {
  718. X               Texture = ((TEXTURE *) Constants[(int)Constant_Id].Constant_Data);
  719. X               Texture_Constant = TRUE;
  720. X               }
  721. X            else
  722. X               Type_Error ();
  723. X         else
  724. X            Undeclared ();
  725. X      END_CASE
  726. X
  727. X      CASE (FLOAT_TOKEN)
  728. X         UNGET
  729. X         if (Texture_Constant) {
  730. X            Texture = Copy_Texture(Texture);
  731. X            Texture_Constant = FALSE;
  732. X            }
  733. X         Texture -> Texture_Randomness = Parse_Float();
  734. X      END_CASE
  735. X
  736. X      CASE (ONCE_TOKEN)
  737. X         if (Texture_Constant) {
  738. X            Texture = Copy_Texture(Texture);
  739. X            Texture_Constant = FALSE;
  740. X            }
  741. X         Texture->Once_Flag = TRUE;
  742. X      END_CASE
  743. X
  744. X      CASE (TURBULENCE_TOKEN)
  745. X         if (Texture_Constant) {
  746. X            Texture = Copy_Texture(Texture);
  747. X            Texture_Constant = FALSE;
  748. X            }
  749. X          Texture -> Turbulence = Parse_Float();
  750. X      END_CASE
  751. X      CASE (BOZO_TOKEN)
  752. X         if (Texture_Constant) {
  753. X            Texture_Constant = FALSE;
  754. X            Texture = Copy_Texture (Texture);
  755. X            }
  756. X         Texture -> Texture_Number = BOZO_TEXTURE;
  757. X      END_CASE
  758. X
  759. X      CASE (CHECKER_TOKEN)
  760. X         if (Texture_Constant) {
  761. X            Texture_Constant = FALSE;
  762. X            Texture = Copy_Texture (Texture);
  763. X            }
  764. X         Texture -> Texture_Number = CHECKER_TEXTURE;
  765. X         EXPECT
  766. X            CASE (COLOUR_TOKEN)
  767. X               Parse_Colour (&(Texture -> Colour1));
  768. X               GET (COLOUR_TOKEN);
  769. X               Parse_Colour (&(Texture -> Colour2));
  770. X            END_CASE
  771. X
  772. X            OTHERWISE
  773. X               UNGET
  774. X               EXIT
  775. X            END_CASE
  776. X         END_EXPECT
  777. X      END_CASE
  778. X
  779. X      CASE (MARBLE_TOKEN)
  780. X         if (Texture_Constant) {
  781. X            Texture_Constant = FALSE;
  782. X            Texture = Copy_Texture (Texture);
  783. X            }
  784. X         Texture -> Texture_Number = MARBLE_TEXTURE;
  785. X      END_CASE
  786. X
  787. X      CASE (WOOD_TOKEN)
  788. X         if (Texture_Constant) {
  789. X            Texture_Constant = FALSE;
  790. X            Texture = Copy_Texture (Texture);
  791. X            }
  792. X         Texture -> Texture_Number = WOOD_TEXTURE;
  793. X      END_CASE
  794. X
  795. X      CASE (SPOTTED_TOKEN)
  796. X         if (Texture_Constant) {
  797. X            Texture_Constant = FALSE;
  798. X            Texture = Copy_Texture (Texture);
  799. X            }
  800. X         Texture -> Texture_Number = SPOTTED_TEXTURE;
  801. X      END_CASE
  802. X
  803. X      CASE (AGATE_TOKEN)
  804. X         if (Texture_Constant) {
  805. X            Texture_Constant = FALSE;
  806. X            Texture = Copy_Texture (Texture);
  807. X            }
  808. X         Texture -> Texture_Number = AGATE_TEXTURE;
  809. X      END_CASE
  810. X
  811. X      CASE (GRANITE_TOKEN)
  812. X         if (Texture_Constant) {
  813. X            Texture_Constant = FALSE;
  814. X            Texture = Copy_Texture (Texture);
  815. X            }
  816. X         Texture -> Texture_Number = GRANITE_TEXTURE;
  817. X      END_CASE
  818. X
  819. X       CASE (GRADIENT_TOKEN)
  820. X         if (Texture_Constant) {
  821. X            Texture_Constant = FALSE;
  822. X            Texture = Copy_Texture (Texture);
  823. X            }
  824. X     Texture -> Texture_Number = GRADIENT_TEXTURE;
  825. X     Parse_Vector (&(Texture -> Texture_Gradient));
  826. X       END_CASE
  827. X      CASE (AMBIENT_TOKEN)
  828. X         if (Texture_Constant) {
  829. X            Texture_Constant = FALSE;
  830. X            Texture = Copy_Texture (Texture);
  831. X            }
  832. X         (Texture -> Object_Ambient) = Parse_Float ();
  833. X      END_CASE
  834. X
  835. X      CASE (BRILLIANCE_TOKEN)
  836. X         if (Texture_Constant) {
  837. X            Texture_Constant = FALSE;
  838. X            Texture = Copy_Texture (Texture);
  839. X            }
  840. X         (Texture -> Object_Brilliance) = Parse_Float ();
  841. X      END_CASE
  842. X
  843. X      CASE (ROUGHNESS_TOKEN)
  844. X         if (Texture_Constant) {
  845. X            Texture_Constant = FALSE;
  846. X            Texture = Copy_Texture (Texture);
  847. X            }
  848. X         (Texture -> Object_Roughness) = Parse_Float ();
  849. X         if (Texture -> Object_Roughness > 1.0)
  850. X            Texture -> Object_Roughness = 1.0;
  851. X         if (Texture -> Object_Roughness < 0.001)
  852. X            Texture -> Object_Roughness = 0.001;
  853. X      END_CASE
  854. X
  855. X      CASE (PHONGSIZE_TOKEN)
  856. X         if (Texture_Constant) {
  857. X            Texture_Constant = FALSE;
  858. X            Texture = Copy_Texture (Texture);
  859. X            }
  860. X         (Texture -> Object_PhongSize) = Parse_Float ();
  861. X         if (Texture -> Object_PhongSize < 1.0)
  862. X            Texture -> Object_PhongSize = 1.0;
  863. X         if (Texture -> Object_PhongSize > 100)
  864. X            Texture -> Object_PhongSize = 100;
  865. X      END_CASE
  866. X
  867. X      CASE (DIFFUSE_TOKEN)
  868. X         if (Texture_Constant) {
  869. X            Texture_Constant = FALSE;
  870. X            Texture = Copy_Texture (Texture);
  871. X            }
  872. X         (Texture -> Object_Diffuse) = Parse_Float ();
  873. X      END_CASE
  874. X
  875. X      CASE (SPECULAR_TOKEN)
  876. X         if (Texture_Constant) {
  877. X            Texture_Constant = FALSE;
  878. X            Texture = Copy_Texture (Texture);
  879. X            }
  880. X         (Texture -> Object_Specular) = Parse_Float ();
  881. X      END_CASE
  882. X
  883. X      CASE (PHONG_TOKEN)
  884. X         if (Texture_Constant) {
  885. X            Texture_Constant = FALSE;
  886. X            Texture = Copy_Texture (Texture);
  887. X            }
  888. X         (Texture -> Object_Phong) = Parse_Float ();
  889. X      END_CASE
  890. X
  891. X      CASE (IOR_TOKEN)
  892. X         if (Texture_Constant) {
  893. X            Texture_Constant = FALSE;
  894. X            Texture = Copy_Texture (Texture);
  895. X            }
  896. X         (Texture -> Object_Index_Of_Refraction) = Parse_Float ();
  897. X      END_CASE
  898. X
  899. X      CASE (REFRACTION_TOKEN)
  900. X         if (Texture_Constant) {
  901. X            Texture_Constant = FALSE;
  902. X            Texture = Copy_Texture (Texture);
  903. X            }
  904. X         (Texture -> Object_Refraction) = Parse_Float ();
  905. X      END_CASE
  906. X
  907. X      CASE (REFLECTION_TOKEN)
  908. X         if (Texture_Constant) {
  909. X            Texture_Constant = FALSE;
  910. X            Texture = Copy_Texture (Texture);
  911. X            }
  912. X         (Texture -> Object_Reflection) = Parse_Float ();
  913. X      END_CASE
  914. X
  915. X      CASE (IMAGEMAP_TOKEN)
  916. X         if (Texture_Constant) {
  917. X            Texture_Constant = FALSE;
  918. X            Texture = Copy_Texture (Texture);
  919. X            }
  920. X         Texture -> Texture_Number = IMAGEMAP_TEXTURE;
  921. X         Texture->Image = (IMAGE *)malloc(sizeof(IMAGE));
  922. X         Make_Vector (&Texture->Texture_Gradient, 1.0, -1.0, 0.0);
  923. X         EXPECT
  924. X            CASE (LEFT_ANGLE_TOKEN)
  925. X                 UNGET
  926. X                 Parse_Vector (&(Texture -> Texture_Gradient));
  927. X            END_CASE
  928. X
  929. X            CASE (IFF_TOKEN)
  930. X               GET (STRING_TOKEN);
  931. X               read_iff_image(Texture->Image, Token.Token_String);
  932. X               EXIT
  933. X            END_CASE
  934. X
  935. X            CASE (GIF_TOKEN)
  936. X               GET (STRING_TOKEN);
  937. X               read_gif_image(Texture->Image, Token.Token_String);
  938. X               EXIT
  939. X            END_CASE
  940. X
  941. X            CASE (RAW_TOKEN)
  942. X               GET (STRING_TOKEN);
  943. X               read_raw_image(Texture->Image, Token.Token_String);
  944. X               EXIT
  945. X            END_CASE
  946. X
  947. X            OTHERWISE
  948. X               Parse_Error (RAW_TOKEN);
  949. X            END_CASE
  950. X         END_EXPECT
  951. X      END_CASE
  952. X
  953. X      CASE (WAVES_TOKEN)
  954. X         if (Texture_Constant) {
  955. X            Texture_Constant = FALSE;
  956. X            Texture = Copy_Texture (Texture);
  957. X            }
  958. X         Texture -> Bump_Number = WAVES;
  959. X         Texture -> Bump_Amount = Parse_Float ();
  960. X         EXPECT
  961. X            CASE (PHASE_TOKEN)
  962. X               Texture -> Phase = Parse_Float();
  963. X               EXIT
  964. X            END_CASE
  965. X
  966. X            OTHERWISE
  967. X               UNGET
  968. X               EXIT
  969. X            END_CASE
  970. X         END_EXPECT
  971. X      END_CASE
  972. X
  973. X      CASE (FREQUENCY_TOKEN)
  974. X         if (Texture_Constant) {
  975. X            Texture_Constant = FALSE;
  976. X            Texture = Copy_Texture (Texture);
  977. X            }
  978. X         Texture -> Frequency = Parse_Float();
  979. X      END_CASE
  980. X
  981. X      CASE (PHASE_TOKEN)
  982. X         if (Texture_Constant) {
  983. X            Texture_Constant = FALSE;
  984. X            Texture = Copy_Texture (Texture);
  985. X            }
  986. X         Texture -> Phase = Parse_Float();
  987. X      END_CASE
  988. X
  989. X      CASE (RIPPLES_TOKEN)
  990. X         if (Texture_Constant) {
  991. X            Texture_Constant = FALSE;
  992. X            Texture = Copy_Texture (Texture);
  993. X            }
  994. X         Texture -> Bump_Number = RIPPLES;
  995. X         Texture -> Bump_Amount = Parse_Float ();
  996. X      END_CASE
  997. X
  998. X      CASE (WRINKLES_TOKEN)
  999. X         if (Texture_Constant) {
  1000. X            Texture_Constant = FALSE;
  1001. X            Texture = Copy_Texture (Texture);
  1002. X            }
  1003. X         Texture -> Bump_Number = WRINKLES;
  1004. X         Texture -> Bump_Amount = Parse_Float ();
  1005. X      END_CASE
  1006. X
  1007. X      CASE (BUMPS_TOKEN)
  1008. X         if (Texture_Constant) {
  1009. X            Texture_Constant = FALSE;
  1010. X            Texture = Copy_Texture (Texture);
  1011. X            }
  1012. X         Texture -> Bump_Number = BUMPS;
  1013. X         Texture -> Bump_Amount = Parse_Float ();
  1014. X      END_CASE
  1015. X
  1016. X      CASE (DENTS_TOKEN)
  1017. X         if (Texture_Constant) {
  1018. X            Texture_Constant = FALSE;
  1019. X            Texture = Copy_Texture (Texture);
  1020. X            }
  1021. X         Texture -> Bump_Number = DENTS;
  1022. X         Texture -> Bump_Amount = Parse_Float ();
  1023. X      END_CASE
  1024. X
  1025. X      CASE (TRANSLATE_TOKEN)
  1026. X         if (Texture_Constant) {
  1027. X            Texture_Constant = FALSE;
  1028. X            Texture = Copy_Texture (Texture);
  1029. X            }
  1030. X         Parse_Vector (&Local_Vector);
  1031. X         if (!Texture -> Texture_Transformation)
  1032. X            Texture -> Texture_Transformation = Get_Transformation ();
  1033. X         Get_Translation_Transformation (&Local_Transformation,
  1034. X                                         &Local_Vector);
  1035. X         Compose_Transformations (Texture -> Texture_Transformation,
  1036. X                                  &Local_Transformation);
  1037. X      END_CASE
  1038. X
  1039. X      CASE (ROTATE_TOKEN)
  1040. X         if (Texture_Constant) {
  1041. X            Texture_Constant = FALSE;
  1042. X            Texture = Copy_Texture (Texture);
  1043. X            }
  1044. X         Parse_Vector (&Local_Vector);
  1045. X         if (!Texture -> Texture_Transformation)
  1046. X            Texture -> Texture_Transformation = Get_Transformation ();
  1047. X         Get_Rotation_Transformation (&Local_Transformation,
  1048. X                                      &Local_Vector);
  1049. X         Compose_Transformations (Texture -> Texture_Transformation,
  1050. X                                  &Local_Transformation);
  1051. X      END_CASE
  1052. X
  1053. X      CASE (SCALE_TOKEN)
  1054. X         if (Texture_Constant) {
  1055. X            Texture_Constant = FALSE;
  1056. X            Texture = Copy_Texture (Texture);
  1057. X            }
  1058. X         Parse_Vector (&Local_Vector);
  1059. X         if (!Texture -> Texture_Transformation)
  1060. X             Texture -> Texture_Transformation = Get_Transformation ();
  1061. X         Get_Scaling_Transformation (&Local_Transformation,
  1062. X                                     &Local_Vector);
  1063. X         Compose_Transformations (Texture -> Texture_Transformation,
  1064. X                                  &Local_Transformation);
  1065. X      END_CASE
  1066. X
  1067. X      CASE2 (COLOUR_MAP_TOKEN, COLOR_MAP_TOKEN)
  1068. X         if (Texture_Constant) {
  1069. X            Texture_Constant = FALSE;
  1070. X            Texture = Copy_Texture (Texture);
  1071. X            }
  1072. X         Texture -> Colour_Map = Parse_Colour_Map();
  1073. X      END_CASE
  1074. X
  1075. X      CASE (END_TEXTURE_TOKEN)
  1076. X         EXIT
  1077. X      END_CASE
  1078. X
  1079. X      OTHERWISE
  1080. X         Parse_Error (END_TEXTURE_TOKEN);
  1081. X      END_CASE
  1082. X   END_EXPECT
  1083. X   return (Texture);
  1084. X   }
  1085. X
  1086. XSHAPE *Parse_Sphere ()
  1087. X  {
  1088. X  SPHERE *Local_Shape;
  1089. X  CONSTANT Constant_Id;
  1090. X  VECTOR Local_Vector;
  1091. X
  1092. X  Local_Shape = NULL;
  1093. X
  1094. X  EXPECT
  1095. X     CASE (LEFT_ANGLE_TOKEN)
  1096. X       UNGET
  1097. X       Local_Shape = Get_Sphere_Shape();
  1098. X       Parse_Vector(&(Local_Shape -> Center));
  1099. X       Local_Shape -> Radius = Parse_Float();
  1100. X       Local_Shape -> Radius_Squared = Local_Shape -> Radius * Local_Shape -> Radius;
  1101. X       Local_Shape -> Inverse_Radius = 1.0 / Local_Shape -> Radius;
  1102. X       EXIT
  1103. X     END_CASE
  1104. X
  1105. X     CASE (IDENTIFIER_TOKEN)
  1106. X       if ((Constant_Id = Find_Constant()) != -1)
  1107. X         if (Constants[(int)Constant_Id].Constant_Type == SPHERE_CONSTANT)
  1108. X           Local_Shape = (SPHERE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1109. X         else
  1110. X           Type_Error ();
  1111. X       else
  1112. X         Undeclared ();
  1113. X       EXIT
  1114. X     END_CASE
  1115. X
  1116. X     OTHERWISE
  1117. X        Parse_Error (LEFT_ANGLE_TOKEN);
  1118. X     END_CASE
  1119. X  END_EXPECT
  1120. X
  1121. X  EXPECT
  1122. X     CASE (END_SPHERE_TOKEN)
  1123. X        EXIT
  1124. X     END_CASE
  1125. X
  1126. X     CASE (TRANSLATE_TOKEN)
  1127. X        Parse_Vector (&Local_Vector);
  1128. X        Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1129. X     END_CASE
  1130. X
  1131. X     CASE (ROTATE_TOKEN)
  1132. X        Parse_Vector (&Local_Vector);
  1133. X        Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1134. X     END_CASE
  1135. X
  1136. X     CASE (SCALE_TOKEN)
  1137. X        Parse_Vector (&Local_Vector);
  1138. X        Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1139. X     END_CASE
  1140. X
  1141. X     CASE (INVERSE_TOKEN)
  1142. X        Invert ((OBJECT *) Local_Shape);
  1143. X     END_CASE
  1144. X
  1145. X     OTHERWISE
  1146. X        Parse_Error (END_SPHERE_TOKEN);
  1147. X     END_CASE
  1148. X  END_EXPECT
  1149. X
  1150. X  return ((SHAPE *) Local_Shape);
  1151. X  }
  1152. X
  1153. XSHAPE *Parse_Plane ()
  1154. X  {
  1155. X  PLANE *Local_Shape;
  1156. X  CONSTANT Constant_Id;
  1157. X  VECTOR Local_Vector;
  1158. X
  1159. X  Local_Shape = NULL;
  1160. X
  1161. X  EXPECT
  1162. X     CASE (LEFT_ANGLE_TOKEN)
  1163. X       UNGET
  1164. X       Local_Shape = Get_Plane_Shape();
  1165. X       Parse_Vector(&(Local_Shape -> Normal_Vector));
  1166. X       Local_Shape->Distance = Parse_Float();
  1167. X       Local_Shape->Distance *= -1.0;
  1168. X       EXIT
  1169. X     END_CASE
  1170. X
  1171. X     CASE (IDENTIFIER_TOKEN)
  1172. X       if ((Constant_Id = Find_Constant()) != -1)
  1173. X         if (Constants[(int)Constant_Id].Constant_Type == PLANE_CONSTANT)
  1174. X           Local_Shape = (PLANE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1175. X         else
  1176. X           Type_Error ();
  1177. X       else
  1178. X         Undeclared ();
  1179. X       EXIT
  1180. X     END_CASE
  1181. X
  1182. X     OTHERWISE
  1183. X        Parse_Error (LEFT_ANGLE_TOKEN);
  1184. X     END_CASE
  1185. X  END_EXPECT
  1186. X
  1187. X  EXPECT
  1188. X     CASE (END_PLANE_TOKEN)
  1189. X        EXIT
  1190. X     END_CASE
  1191. X
  1192. X     CASE (TRANSLATE_TOKEN)
  1193. X        Parse_Vector (&Local_Vector);
  1194. X        Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1195. X     END_CASE
  1196. X
  1197. X     CASE (ROTATE_TOKEN)
  1198. X        Parse_Vector (&Local_Vector);
  1199. X        Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1200. X     END_CASE
  1201. X
  1202. X     CASE (SCALE_TOKEN)
  1203. X        Parse_Vector (&Local_Vector);
  1204. X        Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1205. X     END_CASE
  1206. X
  1207. X     CASE (INVERSE_TOKEN)
  1208. X        Invert ((OBJECT *) Local_Shape);
  1209. X     END_CASE
  1210. X
  1211. X     OTHERWISE
  1212. X        Parse_Error (END_PLANE_TOKEN);
  1213. X     END_CASE
  1214. X  END_EXPECT
  1215. X
  1216. X  return ((SHAPE *) Local_Shape);
  1217. X  }
  1218. X
  1219. XSHAPE *Parse_Triangle ()
  1220. X  {
  1221. X  TRIANGLE *Local_Shape;
  1222. X  CONSTANT Constant_Id;
  1223. X  VECTOR Local_Vector;
  1224. X
  1225. X  Local_Shape = NULL;
  1226. X
  1227. X  EXPECT
  1228. X     CASE (LEFT_ANGLE_TOKEN)
  1229. X       UNGET
  1230. X       Local_Shape = Get_Triangle_Shape();
  1231. X       Parse_Vector (&Local_Shape->P1);
  1232. X       Parse_Vector (&Local_Shape->P2);
  1233. X       Parse_Vector (&Local_Shape->P3);
  1234. X       if (!Compute_Triangle (Local_Shape)) {
  1235. X          printf ("Degenerate triangle on line %d.  Please remove.\n",
  1236. X                  Token.Token_Line_No);
  1237. X          Degenerate_Triangles = TRUE;
  1238. X          }
  1239. X       EXIT
  1240. X     END_CASE
  1241. X
  1242. X     CASE (IDENTIFIER_TOKEN)
  1243. X       if ((Constant_Id = Find_Constant()) != -1)
  1244. X         if (Constants[(int)Constant_Id].Constant_Type == TRIANGLE_CONSTANT)
  1245. X           Local_Shape = (TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1246. X         else
  1247. X           Type_Error ();
  1248. X       else
  1249. X         Undeclared ();
  1250. X       EXIT
  1251. X     END_CASE
  1252. X
  1253. X     OTHERWISE
  1254. X        Parse_Error (LEFT_ANGLE_TOKEN);
  1255. X     END_CASE
  1256. X  END_EXPECT
  1257. X
  1258. X  EXPECT
  1259. X     CASE (END_TRIANGLE_TOKEN)
  1260. X        EXIT
  1261. X     END_CASE
  1262. X
  1263. X     CASE (TRANSLATE_TOKEN)
  1264. X        Parse_Vector (&Local_Vector);
  1265. X        Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1266. X     END_CASE
  1267. X
  1268. X     CASE (ROTATE_TOKEN)
  1269. X        Parse_Vector (&Local_Vector);
  1270. X        Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1271. X     END_CASE
  1272. X
  1273. X     CASE (SCALE_TOKEN)
  1274. X        Parse_Vector (&Local_Vector);
  1275. X        Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1276. X     END_CASE
  1277. X
  1278. X     CASE (INVERSE_TOKEN)
  1279. X        Invert ((OBJECT *) Local_Shape);
  1280. X     END_CASE
  1281. X
  1282. X     OTHERWISE
  1283. X        Parse_Error (END_TRIANGLE_TOKEN);
  1284. X     END_CASE
  1285. X  END_EXPECT
  1286. X
  1287. X  return ((SHAPE *) Local_Shape);
  1288. X  }
  1289. X
  1290. XSHAPE *Parse_Smooth_Triangle ()
  1291. X  {
  1292. X  SMOOTH_TRIANGLE *Local_Shape;
  1293. X  CONSTANT Constant_Id;
  1294. X  VECTOR Local_Vector;
  1295. X
  1296. X  Local_Shape = NULL;
  1297. X
  1298. X  EXPECT
  1299. X     CASE (LEFT_ANGLE_TOKEN)
  1300. X       UNGET
  1301. X       Local_Shape = (SMOOTH_TRIANGLE *) Get_Smooth_Triangle_Shape();
  1302. X       Parse_Vector (&Local_Shape->P1);
  1303. X       Parse_Vector (&Local_Shape->N1);
  1304. X       Parse_Vector (&Local_Shape->P2);
  1305. X       Parse_Vector (&Local_Vector);
  1306. X       VSub (Local_Shape->DN12, Local_Vector, Local_Shape->N1);
  1307. X       Parse_Vector (&Local_Shape->P3);
  1308. X       Parse_Vector (&Local_Vector);
  1309. X       VSub (Local_Shape->DN13, Local_Vector, Local_Shape->N1);
  1310. X       if (!Compute_Triangle ((TRIANGLE *) Local_Shape)) {
  1311. X          printf ("Degenerate triangle on line %d.  Please remove.\n",
  1312. X                  Token.Token_Line_No);
  1313. X          Degenerate_Triangles = TRUE;
  1314. X          }
  1315. X       EXIT
  1316. X     END_CASE
  1317. X
  1318. X     CASE (IDENTIFIER_TOKEN)
  1319. X       if ((Constant_Id = Find_Constant()) != -1)
  1320. X         if (Constants[(int)Constant_Id].Constant_Type == SMOOTH_TRIANGLE_CONSTANT)
  1321. X           Local_Shape = (SMOOTH_TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1322. X         else
  1323. X           Type_Error ();
  1324. X       else
  1325. X         Undeclared ();
  1326. X       EXIT
  1327. X     END_CASE
  1328. X
  1329. X     CASE (TRANSLATE_TOKEN)
  1330. X        Parse_Vector (&Local_Vector);
  1331. X        Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1332. X     END_CASE
  1333. X
  1334. X     CASE (ROTATE_TOKEN)
  1335. X        Parse_Vector (&Local_Vector);
  1336. X        Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1337. X     END_CASE
  1338. X
  1339. X     CASE (SCALE_TOKEN)
  1340. X        Parse_Vector (&Local_Vector);
  1341. X        Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1342. X     END_CASE
  1343. X
  1344. X     CASE (INVERSE_TOKEN)
  1345. X        Invert ((OBJECT *) Local_Shape);
  1346. X     END_CASE
  1347. X
  1348. X     OTHERWISE
  1349. X        Parse_Error (LEFT_ANGLE_TOKEN);
  1350. X     END_CASE
  1351. X  END_EXPECT
  1352. X
  1353. X  EXPECT
  1354. X     CASE (END_TRIANGLE_TOKEN)
  1355. X        EXIT
  1356. X     END_CASE
  1357. X
  1358. X     OTHERWISE
  1359. X        Parse_Error (END_TRIANGLE_TOKEN);
  1360. X     END_CASE
  1361. X  END_EXPECT
  1362. X
  1363. X  return ((SHAPE *) Local_Shape);
  1364. X  }
  1365. X
  1366. XSHAPE *Parse_Quadric ()
  1367. X  {
  1368. X  QUADRIC *Local_Shape;
  1369. X  VECTOR Local_Vector;
  1370. X  CONSTANT Constant_Id;
  1371. X
  1372. X  Local_Shape = NULL;
  1373. X
  1374. X  EXPECT
  1375. X     CASE (LEFT_ANGLE_TOKEN)
  1376. X       UNGET
  1377. X       Local_Shape = Get_Quadric_Shape();
  1378. X       Parse_Vector(&(Local_Shape -> Object_2_Terms));
  1379. X       Parse_Vector(&(Local_Shape -> Object_Mixed_Terms));
  1380. X       Parse_Vector(&(Local_Shape -> Object_Terms));
  1381. X       (Local_Shape -> Object_Constant) = Parse_Float();
  1382. X       Local_Shape -> Non_Zero_Square_Term = 
  1383. X         !((Local_Shape -> Object_2_Terms.x == 0.0)
  1384. X          && (Local_Shape -> Object_2_Terms.y == 0.0)
  1385. X          && (Local_Shape -> Object_2_Terms.z == 0.0)
  1386. X          && (Local_Shape -> Object_Mixed_Terms.x == 0.0)
  1387. X          && (Local_Shape -> Object_Mixed_Terms.y == 0.0)
  1388. X          && (Local_Shape -> Object_Mixed_Terms.z == 0.0));
  1389. X       EXIT
  1390. X     END_CASE
  1391. X
  1392. X     CASE (IDENTIFIER_TOKEN)
  1393. X       if ((Constant_Id = Find_Constant()) != -1)
  1394. X         if (Constants[(int)Constant_Id].Constant_Type == QUADRIC_CONSTANT)
  1395. X           Local_Shape = (QUADRIC *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1396. X         else
  1397. X           Type_Error ();
  1398. X       else
  1399. X         Undeclared ();
  1400. X       EXIT
  1401. X     END_CASE
  1402. X
  1403. X     OTHERWISE
  1404. X        Parse_Error (LEFT_ANGLE_TOKEN);
  1405. X     END_CASE
  1406. X  END_EXPECT
  1407. X
  1408. X  EXPECT
  1409. X     CASE (END_QUADRIC_TOKEN)
  1410. X        EXIT
  1411. X     END_CASE
  1412. X
  1413. X     CASE (TRANSLATE_TOKEN)
  1414. X        Parse_Vector (&Local_Vector);
  1415. X        Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1416. X     END_CASE
  1417. X
  1418. X     CASE (ROTATE_TOKEN)
  1419. X        Parse_Vector (&Local_Vector);
  1420. X        Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1421. X     END_CASE
  1422. X
  1423. X     CASE (SCALE_TOKEN)
  1424. X        Parse_Vector (&Local_Vector);
  1425. X        Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1426. X     END_CASE
  1427. X
  1428. X     CASE (INVERSE_TOKEN)
  1429. X        Invert ((OBJECT *) Local_Shape);
  1430. X     END_CASE
  1431. X
  1432. X     OTHERWISE
  1433. X        Parse_Error (END_QUADRIC_TOKEN);
  1434. X     END_CASE
  1435. X  END_EXPECT
  1436. X
  1437. X  return ((SHAPE *) Local_Shape);
  1438. X  }
  1439. X
  1440. XCSG_SHAPE *Parse_CSG (type, Parent_Object)
  1441. X  int type;
  1442. X  OBJECT *Parent_Object;
  1443. X  {
  1444. X  CSG_SHAPE *Container;
  1445. X  SHAPE *Local_Shape;
  1446. X  VECTOR Local_Vector;
  1447. X  CONSTANT Constant_Id;
  1448. X  int First_Shape_Parsed = FALSE;
  1449. X
  1450. X  if (type == CSG_UNION_TYPE)
  1451. X    Container = Get_CSG_Union ();
  1452. X
  1453. X  else if ((type == CSG_INTERSECTION_TYPE) || (type == CSG_DIFFERENCE_TYPE))
  1454. X    Container = Get_CSG_Intersection ();
  1455. X
  1456. X  Container -> Parent_Object = Parent_Object;
  1457. X
  1458. X  EXPECT
  1459. X     CASE (IDENTIFIER_TOKEN)
  1460. X       if ((Constant_Id = Find_Constant()) != -1)
  1461. X         if ((Constants[(int)Constant_Id].Constant_Type == CSG_INTERSECTION_CONSTANT)
  1462. X             || (Constants[(int)Constant_Id].Constant_Type == CSG_UNION_CONSTANT)
  1463. X             || (Constants[(int)Constant_Id].Constant_Type == CSG_DIFFERENCE_CONSTANT)) {
  1464. X           free (Container);
  1465. X           Container = (CSG_SHAPE *) Copy ((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1466. X           Set_CSG_Parents(Container, Parent_Object);
  1467. X           }
  1468. X         else
  1469. X           Type_Error ();
  1470. X       else
  1471. X         Undeclared ();
  1472. X     END_CASE
  1473. X
  1474. X     CASE (SPHERE_TOKEN)
  1475. X       Local_Shape = Parse_Sphere ();
  1476. X       Local_Shape -> Parent_Object = Parent_Object;
  1477. X       if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1478. X          Invert ((OBJECT *) Local_Shape);
  1479. X       First_Shape_Parsed = TRUE;
  1480. X       Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1481. X               (OBJECT **) &(Container -> Shapes));
  1482. X     END_CASE
  1483. X
  1484. X     CASE (PLANE_TOKEN)
  1485. X       Local_Shape = Parse_Plane ();
  1486. X       Local_Shape -> Parent_Object = Parent_Object;
  1487. X       if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1488. X          Invert ((OBJECT *) Local_Shape);
  1489. X       First_Shape_Parsed = TRUE;
  1490. X       Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1491. X               (OBJECT **) &(Container -> Shapes));
  1492. X     END_CASE
  1493. X
  1494. X     CASE (TRIANGLE_TOKEN)
  1495. X       Local_Shape = Parse_Triangle ();
  1496. X       Local_Shape -> Parent_Object = Parent_Object;
  1497. X       if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1498. X          Invert ((OBJECT *) Local_Shape);
  1499. X       First_Shape_Parsed = TRUE;
  1500. X       Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1501. X               (OBJECT **) &(Container -> Shapes));
  1502. X     END_CASE
  1503. X
  1504. X     CASE (SMOOTH_TRIANGLE_TOKEN)
  1505. X       Local_Shape = Parse_Smooth_Triangle ();
  1506. X       Local_Shape -> Parent_Object = Parent_Object;
  1507. X       if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1508. X          Invert ((OBJECT *) Local_Shape);
  1509. X       First_Shape_Parsed = TRUE;
  1510. X       Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1511. X               (OBJECT **) &(Container -> Shapes));
  1512. X     END_CASE
  1513. X
  1514. X     CASE (QUADRIC_TOKEN)
  1515. X       Local_Shape = Parse_Quadric ();
  1516. X       Local_Shape -> Parent_Object = Parent_Object;
  1517. X       if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1518. X          Invert ((OBJECT *) Local_Shape);
  1519. X       First_Shape_Parsed = TRUE;
  1520. X       Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1521. X               (OBJECT **) &(Container -> Shapes));
  1522. X     END_CASE
  1523. X
  1524. X     CASE (UNION_TOKEN)
  1525. X       Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Parent_Object);
  1526. X       if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1527. X          Invert ((OBJECT *) Local_Shape);
  1528. X       First_Shape_Parsed = TRUE;
  1529. X       Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1530. X               (OBJECT **) &(Container -> Shapes));
  1531. X     END_CASE
  1532. X
  1533. X     CASE (INTERSECTION_TOKEN)
  1534. X       Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Parent_Object);
  1535. X       if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1536. X          Invert ((OBJECT *) Local_Shape);
  1537. X       First_Shape_Parsed = TRUE;
  1538. X       Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1539. X               (OBJECT **) &(Container -> Shapes));
  1540. X     END_CASE
  1541. X
  1542. X     CASE (DIFFERENCE_TOKEN)
  1543. X       Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Parent_Object);
  1544. X       if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1545. X          Invert ((OBJECT *) Local_Shape);
  1546. X       First_Shape_Parsed = TRUE;
  1547. X       Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1548. X               (OBJECT **) &(Container -> Shapes));
  1549. X     END_CASE
  1550. X
  1551. X     OTHERWISE
  1552. X        UNGET
  1553. X        EXIT
  1554. X     END_CASE
  1555. X  END_EXPECT
  1556. X
  1557. X  EXPECT
  1558. X     CASE3 (END_UNION_TOKEN, END_INTERSECTION_TOKEN, END_DIFFERENCE_TOKEN)
  1559. X        EXIT
  1560. X     END_CASE
  1561. X
  1562. X     CASE (TRANSLATE_TOKEN)
  1563. X        Parse_Vector (&Local_Vector);
  1564. X        Translate((OBJECT *) Container, &Local_Vector);
  1565. X     END_CASE
  1566. X
  1567. X     CASE (ROTATE_TOKEN)
  1568. X        Parse_Vector (&Local_Vector);
  1569. X        Rotate ((OBJECT *) Container, &Local_Vector);
  1570. X     END_CASE
  1571. X
  1572. X     CASE (SCALE_TOKEN)
  1573. X        Parse_Vector (&Local_Vector);
  1574. X        Scale ((OBJECT *) Container, &Local_Vector);
  1575. X     END_CASE
  1576. X
  1577. X     CASE (INVERSE_TOKEN)
  1578. X        Invert ((OBJECT *) Container);
  1579. X     END_CASE
  1580. X
  1581. X     OTHERWISE
  1582. X        Parse_Error (END_QUADRIC_TOKEN);
  1583. X     END_CASE
  1584. X  END_EXPECT
  1585. X
  1586. X  return ((CSG_SHAPE *) Container);
  1587. X  }
  1588. X
  1589. XSHAPE *Parse_Shape (Object)
  1590. X  OBJECT *Object;
  1591. X  {
  1592. X  SHAPE *Local_Shape;
  1593. X
  1594. X  EXPECT
  1595. X    CASE (SPHERE_TOKEN)
  1596. X      Local_Shape = Parse_Sphere ();
  1597. X      Local_Shape -> Parent_Object = Object;
  1598. X      EXIT
  1599. X    END_CASE
  1600. X
  1601. X    CASE (PLANE_TOKEN)
  1602. X      Local_Shape = Parse_Plane ();
  1603. X      Local_Shape -> Parent_Object = Object;
  1604. X      EXIT
  1605. X    END_CASE
  1606. X
  1607. X    CASE (TRIANGLE_TOKEN)
  1608. X      Local_Shape = Parse_Triangle ();
  1609. X      Local_Shape -> Parent_Object = Object;
  1610. X      EXIT
  1611. X    END_CASE
  1612. X
  1613. X    CASE (SMOOTH_TRIANGLE_TOKEN)
  1614. X      Local_Shape = Parse_Smooth_Triangle ();
  1615. X      Local_Shape -> Parent_Object = Object;
  1616. X      EXIT
  1617. X    END_CASE
  1618. X
  1619. X    CASE (QUADRIC_TOKEN)
  1620. X      Local_Shape = Parse_Quadric ();
  1621. X      Local_Shape -> Parent_Object = Object;
  1622. X      EXIT
  1623. X    END_CASE
  1624. X
  1625. X    CASE (UNION_TOKEN)
  1626. X      Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Object);
  1627. X      EXIT
  1628. X    END_CASE
  1629. X
  1630. X    CASE (INTERSECTION_TOKEN)
  1631. X      Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Object);
  1632. X      EXIT
  1633. X    END_CASE
  1634. X
  1635. X    CASE (DIFFERENCE_TOKEN)
  1636. X      Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Object);
  1637. X      EXIT
  1638. X    END_CASE
  1639. X
  1640. X    OTHERWISE
  1641. X       Parse_Error (QUADRIC_TOKEN);
  1642. X    END_CASE
  1643. X  END_EXPECT
  1644. X  return (Local_Shape);
  1645. X  }
  1646. X
  1647. XOBJECT *Parse_Object ()
  1648. X  {
  1649. X  OBJECT *Object;
  1650. X  SHAPE *Local_Shape;
  1651. X  VECTOR Local_Vector;
  1652. X  CONSTANT Constant_Id;
  1653. X  int i;
  1654. X
  1655. X  Object = NULL;
  1656. X
  1657. X  EXPECT
  1658. X    CASE (IDENTIFIER_TOKEN)
  1659. X      if ((Constant_Id = Find_Constant()) != -1)
  1660. X        if (Constants[(int)Constant_Id].Constant_Type == OBJECT_CONSTANT)
  1661. X          Object = (OBJECT *) Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1662. X        else
  1663. X          Type_Error ();
  1664. X      else
  1665. X        Undeclared ();
  1666. X      EXIT
  1667. X    END_CASE
  1668. X
  1669. X    CASE5 (SPHERE_TOKEN, QUADRIC_TOKEN, UNION_TOKEN,
  1670. X           INTERSECTION_TOKEN, DIFFERENCE_TOKEN)
  1671. X    CASE3 (TRIANGLE_TOKEN, SMOOTH_TRIANGLE_TOKEN, PLANE_TOKEN)
  1672. X        UNGET
  1673. X        if (Object == NULL)
  1674. X           Object = Get_Object();
  1675. X
  1676. X        Local_Shape = Parse_Shape(Object);
  1677. X        Link((OBJECT *)Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1678. X                (OBJECT **) &(Object -> Shape));
  1679. X        EXIT
  1680. X    END_CASE
  1681. X
  1682. X    OTHERWISE
  1683. X        Parse_Error (QUADRIC_TOKEN);
  1684. X        EXIT
  1685. X    END_CASE
  1686. X  END_EXPECT
  1687. X
  1688. X  EXPECT
  1689. X    CASE (BOUNDED_TOKEN)
  1690. X       EXPECT
  1691. X          CASE (END_BOUNDED_TOKEN)
  1692. X             EXIT
  1693. X          END_CASE
  1694. X
  1695. X          OTHERWISE
  1696. X             UNGET
  1697. X             Local_Shape = Parse_Shape(Object);
  1698. X             Link((OBJECT *) Local_Shape,
  1699. X                  (OBJECT **) &(Local_Shape -> Next_Object),
  1700. X                  (OBJECT **) &(Object -> Bounding_Shapes));
  1701. X          END_CASE
  1702. X       END_EXPECT       
  1703. X    END_CASE
  1704. X
  1705. X    CASE2 (COLOR_TOKEN, COLOUR_TOKEN)
  1706. X       Parse_Colour (&(Object -> Object_Colour));
  1707. X       if (Object->Object_Colour.Alpha != 0.0)
  1708. X          Object->Transparency = TRUE;
  1709. X    END_CASE
  1710. X
  1711. X    CASE (TEXTURE_TOKEN)
  1712. X      Object -> Object_Texture = Parse_Texture (Object->Object_Texture);
  1713. X      if ((Object->Object_Texture->Colour1.Alpha != 0.0) ||
  1714. X          (Object->Object_Texture->Colour2.Alpha != 0.0))
  1715. X         Object->Transparency = TRUE;
  1716. X      else
  1717. X         if (Object->Object_Texture->Colour_Map != NULL)
  1718. X            for (i = 0 ; i < Object->Object_Texture->Colour_Map->Number_Of_Entries ; i++)
  1719. X               if ((Object->Object_Texture->Colour_Map->Colour_Map_Entries[i].Start_Colour.Alpha != 0.0) ||
  1720. X                   (Object->Object_Texture->Colour_Map->Colour_Map_Entries[i].Start_Colour.Alpha != 0.0)) {
  1721. X                  Object->Transparency = TRUE;
  1722. X                  break;
  1723. X                  }
  1724. X    END_CASE
  1725. X
  1726. X    CASE (LIGHT_SOURCE_TOKEN)
  1727. X      Object -> Light_Source_Flag = TRUE;
  1728. X    END_CASE
  1729. X
  1730. X    CASE (TRANSLATE_TOKEN)
  1731. X       Parse_Vector (&Local_Vector);
  1732. X       Translate (Object, &Local_Vector);
  1733. X    END_CASE
  1734. X
  1735. X    CASE (ROTATE_TOKEN)
  1736. X       Parse_Vector (&Local_Vector);
  1737. X       Rotate (Object, &Local_Vector);
  1738. X    END_CASE
  1739. X
  1740. X    CASE (SCALE_TOKEN)
  1741. X       Parse_Vector (&Local_Vector);
  1742. X       Scale (Object, &Local_Vector);
  1743. X    END_CASE
  1744. X
  1745. X    CASE (INVERSE_TOKEN)
  1746. X       Invert (Object);
  1747. X    END_CASE
  1748. X
  1749. X    CASE (AMBIENT_TOKEN)
  1750. X      if (Object -> Object_Texture == Default_Texture)
  1751. X         Object -> Object_Texture = Get_Texture();
  1752. X
  1753. X      (Object -> Object_Texture -> Object_Ambient) = Parse_Float ();
  1754. X    END_CASE
  1755. X
  1756. X    CASE (BRILLIANCE_TOKEN)
  1757. X      if (Object -> Object_Texture == Default_Texture)
  1758. X         Object -> Object_Texture = Get_Texture();
  1759. X
  1760. X      (Object -> Object_Texture -> Object_Brilliance) = Parse_Float ();
  1761. X    END_CASE
  1762. X
  1763. X    CASE (ROUGHNESS_TOKEN)
  1764. X      if (Object -> Object_Texture == Default_Texture)
  1765. X         Object -> Object_Texture = Get_Texture();
  1766. X
  1767. X      (Object -> Object_Texture -> Object_Roughness) = Parse_Float ();
  1768. X      if (Object -> Object_Texture -> Object_Roughness > 1.0)
  1769. X         Object -> Object_Texture -> Object_Roughness = 1.0;
  1770. X      if (Object -> Object_Texture -> Object_Roughness < 0.001)
  1771. X         Object -> Object_Texture -> Object_Roughness = 0.001;
  1772. X    END_CASE
  1773. X
  1774. X    CASE (PHONGSIZE_TOKEN)
  1775. X      if (Object -> Object_Texture == Default_Texture)
  1776. X         Object -> Object_Texture = Get_Texture();
  1777. X
  1778. X      (Object -> Object_Texture -> Object_PhongSize) = Parse_Float ();
  1779. X      if (Object -> Object_Texture -> Object_PhongSize < 1.0)
  1780. X         Object -> Object_Texture -> Object_PhongSize = 1.0;
  1781. X      if (Object -> Object_Texture -> Object_PhongSize > 100)
  1782. X         Object -> Object_Texture -> Object_PhongSize = 100;
  1783. X    END_CASE
  1784. X
  1785. X    CASE (DIFFUSE_TOKEN)
  1786. X      if (Object -> Object_Texture == Default_Texture)
  1787. X         Object -> Object_Texture = Get_Texture();
  1788. X
  1789. X      (Object -> Object_Texture -> Object_Diffuse) = Parse_Float ();
  1790. X    END_CASE
  1791. X
  1792. X    CASE (SPECULAR_TOKEN)
  1793. X      if (Object -> Object_Texture == Default_Texture)
  1794. X         Object -> Object_Texture = Get_Texture();
  1795. X
  1796. X      (Object -> Object_Texture -> Object_Specular) = Parse_Float ();
  1797. X    END_CASE
  1798. X
  1799. X    CASE (PHONG_TOKEN)
  1800. X      if (Object -> Object_Texture == Default_Texture)
  1801. X         Object -> Object_Texture = Get_Texture();
  1802. X
  1803. X      (Object -> Object_Texture -> Object_Phong) = Parse_Float ();
  1804. X    END_CASE
  1805. X
  1806. X    CASE (IOR_TOKEN)
  1807. X      if (Object -> Object_Texture == Default_Texture)
  1808. X         Object -> Object_Texture = Get_Texture();
  1809. X
  1810. X      (Object -> Object_Texture -> Object_Index_Of_Refraction) = Parse_Float ();
  1811. X    END_CASE
  1812. X
  1813. X    CASE (REFRACTION_TOKEN)
  1814. X      if (Object -> Object_Texture == Default_Texture)
  1815. X         Object -> Object_Texture = Get_Texture();
  1816. X
  1817. X      (Object -> Object_Texture -> Object_Refraction) = Parse_Float ();
  1818. X    END_CASE
  1819. X
  1820. X    CASE (REFLECTION_TOKEN)
  1821. X      if (Object -> Object_Texture == Default_Texture)
  1822. X         Object -> Object_Texture = Get_Texture();
  1823. X
  1824. X      (Object -> Object_Texture -> Object_Reflection) = Parse_Float ();
  1825. X    END_CASE
  1826. X
  1827. X    CASE (END_OBJECT_TOKEN)
  1828. X      EXIT
  1829. X    END_CASE
  1830. X
  1831. X    OTHERWISE
  1832. X      Parse_Error (END_OBJECT_TOKEN);
  1833. X    END_CASE
  1834. X
  1835. X  END_EXPECT
  1836. X
  1837. X  return (Object);
  1838. X  }
  1839. X
  1840. XOBJECT *Parse_Composite ()
  1841. X  {
  1842. X  COMPOSITE *Local_Composite;
  1843. X  OBJECT *Local_Object;
  1844. X  SHAPE *Local_Shape;
  1845. X  CONSTANT Constant_Id;
  1846. X  VECTOR Local_Vector;
  1847. X
  1848. X  Local_Composite = NULL;
  1849. X
  1850. X  EXPECT
  1851. X    CASE (IDENTIFIER_TOKEN)
  1852. X      if ((Constant_Id = Find_Constant()) != -1)
  1853. X        if (Constants[(int)Constant_Id].Constant_Type == COMPOSITE_CONSTANT)
  1854. X          Local_Composite = (COMPOSITE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1855. X        else          
  1856. X          Type_Error ();
  1857. X      else
  1858. X        Undeclared ();
  1859. X    END_CASE
  1860. X
  1861. X    CASE (COMPOSITE_TOKEN)
  1862. X      if (Local_Composite == NULL)       
  1863. X           Local_Composite = Get_Composite_Object();
  1864. X
  1865. X      Local_Object = Parse_Composite();
  1866. X      Link((OBJECT *) Local_Object,(OBJECT **) &(Local_Object -> Next_Object),
  1867. X              (OBJECT **) &(Local_Composite -> Objects));
  1868. X    END_CASE
  1869. X
  1870. X    CASE (OBJECT_TOKEN)
  1871. X      if (Local_Composite == NULL)       
  1872. X           Local_Composite = Get_Composite_Object();
  1873. X
  1874. X      Local_Object = Parse_Object();
  1875. X      Link(Local_Object, &(Local_Object -> Next_Object),
  1876. X               &(Local_Composite -> Objects));
  1877. X
  1878. X      if (Local_Object -> Light_Source_Flag)
  1879. X         Link(Local_Object, &(Local_Object -> Next_Light_Source),
  1880. X               &(Parsing_Frame_Ptr -> Light_Sources));
  1881. X    END_CASE
  1882. X
  1883. X    CASE (END_COMPOSITE_TOKEN)
  1884. X      UNGET
  1885. X      if (Local_Composite == NULL)       
  1886. X        Local_Composite = Get_Composite_Object();
  1887. X
  1888. X      EXIT
  1889. X    END_CASE
  1890. X
  1891. X    OTHERWISE
  1892. X       UNGET
  1893. X       EXIT
  1894. X    END_CASE
  1895. X  END_EXPECT
  1896. X
  1897. X  EXPECT
  1898. X    CASE (END_COMPOSITE_TOKEN)
  1899. X       EXIT
  1900. X    END_CASE
  1901. X
  1902. X    CASE (BOUNDED_TOKEN)
  1903. X       EXPECT
  1904. X          CASE (END_BOUNDED_TOKEN)
  1905. X             EXIT
  1906. X          END_CASE
  1907. X
  1908. X          OTHERWISE
  1909. X             UNGET
  1910. X             Local_Shape = Parse_Shape((OBJECT *) Local_Composite);
  1911. X             Link((OBJECT *) Local_Shape,
  1912. X                  (OBJECT **) &(Local_Shape -> Next_Object),
  1913. X                  (OBJECT **) &(Local_Composite -> Bounding_Shapes));
  1914. X          END_CASE
  1915. X       END_EXPECT       
  1916. X    END_CASE
  1917. X
  1918. X    CASE (TRANSLATE_TOKEN)
  1919. X       Parse_Vector (&Local_Vector);
  1920. X       Translate ((OBJECT *) Local_Composite, &Local_Vector);
  1921. X    END_CASE
  1922. X
  1923. X    CASE (ROTATE_TOKEN)
  1924. X       Parse_Vector (&Local_Vector);
  1925. X       Rotate ((OBJECT *) Local_Composite, &Local_Vector);
  1926. X    END_CASE
  1927. X
  1928. X    CASE (SCALE_TOKEN)
  1929. X       Parse_Vector (&Local_Vector);
  1930. X       Scale ((OBJECT *) Local_Composite, &Local_Vector);
  1931. X    END_CASE
  1932. X
  1933. X     CASE (INVERSE_TOKEN)
  1934. X        Invert ((OBJECT *) Local_Composite);
  1935. X     END_CASE
  1936. X
  1937. X    OTHERWISE
  1938. X       Parse_Error (END_COMPOSITE_TOKEN);
  1939. X    END_CASE
  1940. X  END_EXPECT
  1941. X
  1942. X  return ((OBJECT *) Local_Composite);
  1943. X  }
  1944. X
  1945. Xvoid Parse_Fog ()
  1946. X   {
  1947. X   EXPECT
  1948. X      CASE (COLOUR_TOKEN)
  1949. X         Parse_Colour (&Parsing_Frame_Ptr->Fog_Colour);
  1950. X      END_CASE
  1951. X
  1952. X      CASE (FLOAT_TOKEN)
  1953. X         Parsing_Frame_Ptr->Fog_Distance = Token.Token_Float;
  1954. X      END_CASE
  1955. X
  1956. X      CASE (END_FOG_TOKEN)
  1957. X         EXIT
  1958. X      END_CASE
  1959. X
  1960. X      OTHERWISE
  1961. X         Parse_Error (END_FOG_TOKEN);
  1962. X      END_CASE
  1963. X   END_EXPECT
  1964. X   }
  1965. X
  1966. Xvoid Parse_Frame ()
  1967. X  {
  1968. X  OBJECT *Local_Object;
  1969. X
  1970. X  EXPECT
  1971. X    CASE (FOG_TOKEN)
  1972. X       Parse_Fog();
  1973. X    END_CASE
  1974. X
  1975. X    CASE (OBJECT_TOKEN)
  1976. X      Local_Object = Parse_Object();
  1977. X      Link(Local_Object, &(Local_Object -> Next_Object),
  1978. X             &(Parsing_Frame_Ptr -> Objects));
  1979. X
  1980. X      if (Local_Object -> Light_Source_Flag)
  1981. X         Link(Local_Object, &(Local_Object -> Next_Light_Source),
  1982. X               &(Parsing_Frame_Ptr -> Light_Sources));
  1983. X    END_CASE
  1984. X
  1985. X    CASE (COMPOSITE_TOKEN)
  1986. X      Local_Object = Parse_Composite();
  1987. X      Link(Local_Object, &(Local_Object -> Next_Object),
  1988. X            &(Parsing_Frame_Ptr -> Objects));
  1989. X    END_CASE
  1990. X
  1991. X    CASE (VIEW_POINT_TOKEN)
  1992. X      Parse_Viewpoint(&(Parsing_Frame_Ptr -> View_Point));
  1993. X    END_CASE
  1994. X
  1995. X    CASE (DECLARE_TOKEN)
  1996. X      Parse_Declare ();
  1997. X    END_CASE
  1998. X
  1999. X    CASE (END_OF_FILE_TOKEN)
  2000. X      EXIT
  2001. X    END_CASE
  2002. X
  2003. X    OTHERWISE 
  2004. X      Parse_Error (OBJECT_TOKEN);
  2005. X    END_CASE
  2006. X  END_EXPECT
  2007. X  }
  2008. X
  2009. Xvoid Parse_Viewpoint (Given_Vp)
  2010. X  VIEWPOINT *Given_Vp;
  2011. X  {
  2012. X  CONSTANT Constant_Id;
  2013. X  VECTOR Local_Vector, Temp_Vector;
  2014. X  DBL Direction_Length, Up_Length, Right_Length, Handedness;
  2015. X
  2016. X  Init_Viewpoint (Given_Vp);
  2017. X
  2018. X  EXPECT
  2019. X    CASE (IDENTIFIER_TOKEN)
  2020. X      if ((Constant_Id = Find_Constant()) != -1)
  2021. X        if (Constants[(int)Constant_Id].Constant_Type == VIEW_POINT_CONSTANT)
  2022. X          *Given_Vp = 
  2023. X             *((VIEWPOINT*) Constants[(int)Constant_Id].Constant_Data);
  2024. X        else
  2025. X          Type_Error ();
  2026. X      else
  2027. X        Undeclared ();
  2028. X    END_CASE
  2029. X
  2030. X    CASE (LOCATION_TOKEN)
  2031. X      Parse_Vector(&(Given_Vp -> Location));
  2032. X    END_CASE
  2033. X
  2034. X    CASE (DIRECTION_TOKEN)
  2035. X      Parse_Vector(&(Given_Vp -> Direction));
  2036. X    END_CASE
  2037. X
  2038. X    CASE (UP_TOKEN)
  2039. X      Parse_Vector(&(Given_Vp -> Up));
  2040. X    END_CASE
  2041. X
  2042. X    CASE (RIGHT_TOKEN)
  2043. X      Parse_Vector(&(Given_Vp -> Right));
  2044. X    END_CASE
  2045. X
  2046. X    CASE (SKY_TOKEN)
  2047. X      Parse_Vector(&(Given_Vp -> Sky));
  2048. X    END_CASE
  2049. X
  2050. X    CASE (LOOK_AT_TOKEN)
  2051. X       VLength (Direction_Length, Given_Vp->Direction);
  2052. X       VLength (Up_Length, Given_Vp->Up);
  2053. X       VLength (Right_Length, Given_Vp->Right);
  2054. X       VCross (Temp_Vector, Given_Vp->Direction, Given_Vp->Up);
  2055. X       VDot (Handedness, Temp_Vector, Given_Vp->Right);
  2056. X       Parse_Vector(&Given_Vp->Direction);
  2057. X
  2058. X       VSub (Given_Vp->Direction, Given_Vp->Direction, Given_Vp->Location);
  2059. X       VNormalize (Given_Vp->Direction, Given_Vp->Direction);
  2060. X       VCross(Given_Vp->Right, Given_Vp->Direction, Given_Vp->Sky);
  2061. X       VNormalize (Given_Vp->Right, Given_Vp->Right);
  2062. X       VCross (Given_Vp->Up, Given_Vp->Right, Given_Vp->Direction);
  2063. X       VScale (Given_Vp->Direction, Given_Vp->Direction, Direction_Length);
  2064. X       if (Handedness >= 0.0) {
  2065. X          VScale (Given_Vp->Right, Given_Vp->Right, Right_Length);
  2066. X          }
  2067. X       else {
  2068. X          VScale (Given_Vp->Right, Given_Vp->Right, -Right_Length);
  2069. X          }
  2070. X
  2071. X       VScale (Given_Vp->Up, Given_Vp->Up, Up_Length);       
  2072. X    END_CASE
  2073. X
  2074. X    CASE (TRANSLATE_TOKEN)
  2075. X       Parse_Vector (&Local_Vector);
  2076. X       Translate ((OBJECT *) Given_Vp, &Local_Vector);
  2077. X    END_CASE
  2078. X
  2079. X    CASE (ROTATE_TOKEN)
  2080. X       Parse_Vector (&Local_Vector);
  2081. X       Rotate ((OBJECT *) Given_Vp, &Local_Vector);
  2082. X    END_CASE
  2083. X
  2084. X    CASE (SCALE_TOKEN)
  2085. X       Parse_Vector (&Local_Vector);
  2086. X       Scale ((OBJECT *) Given_Vp, &Local_Vector);
  2087. X    END_CASE
  2088. X
  2089. X    CASE (END_VIEW_POINT_TOKEN)
  2090. X      EXIT
  2091. X    END_CASE
  2092. X
  2093. X    OTHERWISE
  2094. X      Parse_Error (END_VIEW_POINT_TOKEN);
  2095. X    END_CASE
  2096. X  END_EXPECT
  2097. X  }
  2098. X
  2099. Xvoid Parse_Declare ()
  2100. X  {
  2101. X  CONSTANT Constant_Id;
  2102. X
  2103. X  struct Constant_Struct *Constant_Ptr;
  2104. X
  2105. X  GET (IDENTIFIER_TOKEN);
  2106. X  if ((Constant_Id = Find_Constant()) == -1)
  2107. X    if (++Number_Of_Constants >= MAX_CONSTANTS)
  2108. X      Error ("Too many constants");
  2109. X    else
  2110. X      Constant_Id = Number_Of_Constants;
  2111. X
  2112. X  Constant_Ptr = &(Constants[(int)Constant_Id]);
  2113. X  GET (EQUALS_TOKEN);
  2114. X
  2115. X  EXPECT
  2116. X    CASE (OBJECT_TOKEN)
  2117. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2118. X      Constant_Ptr -> Constant_Data = (char *) Parse_Object();
  2119. X      Constant_Ptr -> Constant_Type = OBJECT_CONSTANT;
  2120. X      EXIT
  2121. X    END_CASE
  2122. X
  2123. X    CASE (SPHERE_TOKEN)
  2124. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2125. X      Constant_Ptr -> Constant_Data = (char *) Parse_Sphere ();
  2126. X      Constant_Ptr -> Constant_Type = SPHERE_CONSTANT;
  2127. X      EXIT
  2128. X    END_CASE
  2129. X
  2130. X    CASE (PLANE_TOKEN)
  2131. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2132. X      Constant_Ptr -> Constant_Data = (char *) Parse_Plane ();
  2133. X      Constant_Ptr -> Constant_Type = PLANE_CONSTANT;
  2134. X      EXIT
  2135. X    END_CASE
  2136. X
  2137. X    CASE (TRIANGLE_TOKEN)
  2138. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2139. X      Constant_Ptr -> Constant_Data = (char *) Parse_Triangle ();
  2140. X      Constant_Ptr -> Constant_Type = TRIANGLE_CONSTANT;
  2141. X      EXIT
  2142. X    END_CASE
  2143. X
  2144. X    CASE (SMOOTH_TRIANGLE_TOKEN)
  2145. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2146. X      Constant_Ptr -> Constant_Data = (char *) Parse_Smooth_Triangle ();
  2147. X      Constant_Ptr -> Constant_Type = SMOOTH_TRIANGLE_CONSTANT;
  2148. X      EXIT
  2149. X    END_CASE
  2150. X
  2151. X    CASE (QUADRIC_TOKEN)
  2152. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2153. X      Constant_Ptr -> Constant_Data = (char *) Parse_Quadric ();
  2154. X      Constant_Ptr -> Constant_Type = QUADRIC_CONSTANT;
  2155. X      EXIT
  2156. X    END_CASE
  2157. X
  2158. X    CASE (INTERSECTION_TOKEN)
  2159. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2160. X      Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_INTERSECTION_TYPE, NULL);
  2161. X      Constant_Ptr -> Constant_Type = CSG_INTERSECTION_CONSTANT;
  2162. X      EXIT
  2163. X    END_CASE
  2164. X
  2165. X    CASE (UNION_TOKEN)
  2166. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2167. X      Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_UNION_TYPE, NULL);
  2168. X      Constant_Ptr -> Constant_Type = CSG_UNION_CONSTANT;
  2169. X      EXIT
  2170. X    END_CASE
  2171. X
  2172. X    CASE (DIFFERENCE_TOKEN)
  2173. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2174. X      Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_DIFFERENCE_TYPE, NULL);
  2175. X      Constant_Ptr -> Constant_Type = CSG_DIFFERENCE_CONSTANT;
  2176. X      EXIT
  2177. X    END_CASE
  2178. X
  2179. X    CASE (COMPOSITE_TOKEN)
  2180. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2181. X      Constant_Ptr -> Constant_Data = (char *) Parse_Composite();
  2182. X      Constant_Ptr -> Constant_Type = COMPOSITE_CONSTANT;
  2183. X      EXIT
  2184. X    END_CASE
  2185. X
  2186. X    CASE (TEXTURE_TOKEN)
  2187. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2188. X      Constant_Ptr -> Constant_Data = (char *) Parse_Texture(Default_Texture);
  2189. X      Constant_Ptr -> Constant_Type = TEXTURE_CONSTANT;
  2190. X      EXIT
  2191. X    END_CASE
  2192. X
  2193. X    CASE (VIEW_POINT_TOKEN)
  2194. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2195. X      Constant_Ptr -> Constant_Data = (char *) Get_Viewpoint();
  2196. X      Constant_Ptr -> Constant_Type = VIEW_POINT_CONSTANT;
  2197. X      Parse_Viewpoint((VIEWPOINT *) Constant_Ptr -> Constant_Data);
  2198. X      EXIT
  2199. X    END_CASE
  2200. X
  2201. X    CASE2 (COLOR_TOKEN, COLOUR_TOKEN)
  2202. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2203. X      Constant_Ptr -> Constant_Data = (char *) Get_Colour();
  2204. X      Constant_Ptr -> Constant_Type = COLOUR_CONSTANT;
  2205. X      Parse_Colour ((COLOUR *) Constant_Ptr -> Constant_Data);
  2206. X      EXIT
  2207. X    END_CASE
  2208. X
  2209. X    CASE (LEFT_ANGLE_TOKEN)
  2210. X      UNGET
  2211. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2212. X      Constant_Ptr -> Constant_Data = (char *) Get_Vector();
  2213. X      Constant_Ptr -> Constant_Type = VECTOR_CONSTANT;
  2214. X      Parse_Vector((VECTOR *) Constant_Ptr -> Constant_Data);
  2215. X      EXIT
  2216. X    END_CASE
  2217. X
  2218. X    CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  2219. X      UNGET
  2220. X      Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2221. X      Constant_Ptr -> Constant_Data = (char *) Get_Float();
  2222. X      Constant_Ptr -> Constant_Type = FLOAT_CONSTANT;
  2223. X      *(Constant_Ptr -> Constant_Data) = Parse_Float();
  2224. X      EXIT
  2225. X    END_CASE
  2226. X
  2227. X    OTHERWISE
  2228. X      Parse_Error (OBJECT_TOKEN);
  2229. X    END_CASE
  2230. X  END_EXPECT
  2231. X  }
  2232. X
  2233. Xvoid Init_Viewpoint (vp)
  2234. X  VIEWPOINT *vp;
  2235. X  {
  2236. X  vp -> Methods = (void *) &Viewpoint_Methods;
  2237. X  vp -> Type = VIEWPOINT_TYPE;
  2238. X  Make_Vector (&vp->Location, 0.0, 0.0, 0.0);
  2239. X  Make_Vector (&vp->Direction, 0.0, 0.0, 1.0);
  2240. X  Make_Vector (&vp->Up, 0.0, 1.0, 0.0);
  2241. X  Make_Vector (&vp->Right, 1.0, 0.0, 0.0);
  2242. X  Make_Vector (&vp->Sky, 0.0, 1.0, 0.0);
  2243. X  }
  2244. X
  2245. Xvoid Link (New_Object, Field, Old_Object_List)
  2246. X  OBJECT *New_Object, **Field, **Old_Object_List;
  2247. X  {
  2248. X  *Field = *Old_Object_List;
  2249. X  *Old_Object_List = New_Object;
  2250. X  }
  2251. X
  2252. XCONSTANT Find_Constant()
  2253. X  {
  2254. X  register int i;
  2255. X
  2256. X  for (i = 1 ; i <= Number_Of_Constants ; i++)
  2257. X    if (Constants [i].Identifier_Number == Token.Identifier_Number)
  2258. X      return (i);
  2259. X
  2260. X  return (-1);
  2261. X  }
  2262. X
  2263. X
  2264. Xchar *Get_Token_String (Token_Id)
  2265. X  TOKEN Token_Id;
  2266. X  {
  2267. X  register int i;
  2268. X
  2269. X  for (i = 0 ; i < LAST_TOKEN ; i++)
  2270. X     if (Reserved_Words[i].Token_Number == Token_Id)
  2271. X        return (Reserved_Words[i].Token_Name);
  2272. X  return ("");
  2273. X  }
  2274. X
  2275. Xvoid Parse_Error (Token_Id)
  2276. X  TOKEN Token_Id;
  2277. X  {
  2278. X  char *expected, *found;
  2279. X
  2280. X  fprintf (stderr, "Error in file %s line %d\n", Current_File_Name,
  2281. X                                                 Token.Token_Line_No);
  2282. X  expected = Get_Token_String (Token_Id);
  2283. X  found = Get_Token_String (Token.Token_Id);
  2284. X  fprintf (stderr, "%s expected but %s found instead\n", expected, found);
  2285. X  exit(0);
  2286. X  }
  2287. X
  2288. Xvoid Type_Error ()
  2289. X  {
  2290. X  fprintf (stderr, "Error in file %s line %d\n", Current_File_Name,
  2291. X                                                 Token.Token_Line_No);
  2292. X  fprintf (stderr, "Identifier %s is the wrong type\n",
  2293. X            &Token.Token_String[0]);
  2294. X  exit (0);
  2295. X  }
  2296. X
  2297. Xvoid Undeclared ()
  2298. X  {
  2299. X  fprintf (stderr, "Error in file %s line %d\n", Current_File_Name,
  2300. X                                                 Token.Token_Line_No);
  2301. X  fprintf (stderr, "Undeclared identifier %s\n", &Token.Token_String[0]);
  2302. X  exit (0);
  2303. X  }
  2304. X
  2305. Xvoid Error (str)
  2306. X  char *str;
  2307. X  {
  2308. X  fprintf (stderr, "Error in file %s line %d\n", Current_File_Name,
  2309. X                                                 Token.Token_Line_No);
  2310. X  fputs (str, stderr);
  2311. X  exit (0);
  2312. X  }
  2313. X
  2314. END_OF_FILE
  2315. if test 63678 -ne `wc -c <'src/parse.c'`; then
  2316.     echo shar: \"'src/parse.c'\" unpacked with wrong size!
  2317. fi
  2318. # end of 'src/parse.c'
  2319. fi
  2320. echo shar: End of archive 9 \(of 10\).
  2321. cp /dev/null ark9isdone
  2322. MISSING=""
  2323. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  2324.     if test ! -f ark${I}isdone ; then
  2325.     MISSING="${MISSING} ${I}"
  2326.     fi
  2327. done
  2328. if test "${MISSING}" = "" ; then
  2329.     echo You have unpacked all 10 archives.
  2330.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2331. else
  2332.     echo You still need to unpack the following archives:
  2333.     echo "        " ${MISSING}
  2334. fi
  2335. ##  End of shell archive.
  2336. exit 0
  2337. -- 
  2338. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2339. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2340. Post requests for sources, and general discussion to comp.sys.amiga.
  2341.